import { useState, useCallback, useRef, useEffect } from 'react';
import type { Room, RoomAvailability } from '../../../types/room';
import { RoomStatus } from '../../../types/room';
import { RoomStatusManager } from '../utils/RoomStatusManager';

// 增强拖拽状态枚举
export const AdvancedDragState = {
  IDLE: 'idle',
  PREPARING: 'preparing', // 准备拖拽
  DRAGGING: 'dragging',
  HOVERING: 'hovering',
  SNAPPING: 'snapping', // 磁吸效果
  COMPLETING: 'completing', // 完成拖拽
} as const;

export type AdvancedDragState =
  (typeof AdvancedDragState)[keyof typeof AdvancedDragState];

// 拖拽手势识别
export interface DragGesture {
  velocity: { x: number; y: number };
  direction: 'horizontal' | 'vertical' | 'diagonal';
  distance: number;
  duration: number;
  isFlick: boolean; // 快速甩动
  isSlow: boolean; // 缓慢拖拽
}

// 磁吸配置
export interface SnapConfig {
  enabled: boolean;
  threshold: number; // 磁吸距离阈值
  strength: number; // 磁吸强度 (0-1)
  zones: SnapZone[];
}

export interface SnapZone {
  x: number;
  y: number;
  width: number;
  height: number;
  roomId: string;
  date: string;
  priority: number; // 磁吸优先级
}

// 增强拖拽数据
export interface AdvancedDragData {
  sourceRoom: Room;
  sourceDate: string;
  sourceStatus: RoomStatus;
  startPosition: { x: number; y: number };
  currentPosition: { x: number; y: number };
  offset: { x: number; y: number };
  cellBounds: { x: number; y: number; width: number; height: number };
  startTime: number;
  gesture: DragGesture;
  trail: Array<{ x: number; y: number; timestamp: number }>;
}

// 拖拽目标增强
export interface AdvancedDropTarget {
  room: Room;
  date: string;
  position: { x: number; y: number };
  isValid: boolean;
  canDrop: boolean;
  reason?: string;
  confidence: number; // 目标置信度 (0-1)
  snapDistance: number; // 到磁吸点的距离
}

// 拖拽反馈配置
export interface DragFeedback {
  haptics: boolean; // 触觉反馈
  sound: boolean; // 声音反馈
  visual: boolean; // 视觉反馈
  cursor: 'grab' | 'grabbing' | 'not-allowed' | 'copy' | 'move';
}

// 增强拖拽状态
export interface AdvancedDragDropState {
  state: AdvancedDragState;
  dragData: AdvancedDragData | null;
  dropTarget: AdvancedDropTarget | null;
  snapTarget: SnapZone | null;
  isDragging: boolean;
  canDrop: boolean;
  isSnapping: boolean;
  feedback: DragFeedback;
  performance: {
    frameRate: number;
    renderTime: number;
    memoryUsage: number;
  };
}

interface UseAdvancedDragDropConfig {
  snapConfig?: SnapConfig;
  feedbackConfig?: Partial<DragFeedback>;
  performanceMode?: 'high' | 'balanced' | 'battery';
  enableGestures?: boolean;
  enablePrediction?: boolean; // 预测拖拽目标
}

interface UseAdvancedDragDropReturn {
  dragState: AdvancedDragDropState;
  startDrag: (
    event: React.MouseEvent | React.TouchEvent,
    room: Room,
    date: string,
    status: RoomStatus,
    cellBounds: { x: number; y: number; width: number; height: number }
  ) => void;
  updateDrag: (event: React.MouseEvent | React.TouchEvent) => void;
  endDrag: () => void;
  cancelDrag: () => void;
  renderDragPreview: (ctx: CanvasRenderingContext2D) => void;
  setSnapZones: (zones: SnapZone[]) => void;
}

export const useAdvancedDragDrop = (
  rooms: Room[],
  dates: string[],
  availabilities: RoomAvailability[],
  config: {
    cellWidth: number;
    cellHeight: number;
    roomTypeWidth: number;
    roomNumberWidth: number;
  },
  onDragComplete: (
    sourceRoom: Room,
    sourceDate: string,
    targetRoom: Room,
    targetDate: string
  ) => void,
  advancedConfig: UseAdvancedDragDropConfig = {}
): UseAdvancedDragDropReturn => {
  const {
    snapConfig = { enabled: true, threshold: 30, strength: 0.8, zones: [] },
    feedbackConfig = {
      haptics: true,
      sound: false,
      visual: true,
      cursor: 'grab',
    },
    performanceMode = 'balanced',
    enableGestures = true,
    enablePrediction = true,
  } = advancedConfig;

  // 状态管理
  const [dragState, setDragState] = useState<AdvancedDragDropState>({
    state: AdvancedDragState.IDLE,
    dragData: null,
    dropTarget: null,
    snapTarget: null,
    isDragging: false,
    canDrop: false,
    isSnapping: false,
    feedback: {
      haptics: true,
      sound: false,
      visual: true,
      cursor: 'grab',
      ...feedbackConfig,
    },
    performance: { frameRate: 60, renderTime: 0, memoryUsage: 0 },
  });

  // 引用和定时器
  const rafRef = useRef<number>();
  const performanceRef = useRef({ lastFrame: 0, frameCount: 0 });
  const gestureRef = useRef<{
    startTime: number;
    positions: Array<{ x: number; y: number; time: number }>;
  }>({
    startTime: 0,
    positions: [],
  });

  // 磁吸区域管理
  const [snapZones, setSnapZones] = useState<SnapZone[]>(snapConfig.zones);

  // 性能监控
  const updatePerformance = useCallback(() => {
    const now = performance.now();
    const frameTime = now - performanceRef.current.lastFrame;
    const fps = 1000 / frameTime;

    performanceRef.current.frameCount++;
    performanceRef.current.lastFrame = now;

    // 每60帧更新一次性能指标
    if (performanceRef.current.frameCount % 60 === 0) {
      setDragState(prev => ({
        ...prev,
        performance: {
          frameRate: Math.round(fps),
          renderTime: frameTime,
          memoryUsage: (performance as any).memory?.usedJSHeapSize || 0,
        },
      }));
    }
  }, []);

  // 手势识别
  const analyzeGesture = useCallback(
    (dragData: AdvancedDragData): DragGesture => {
      const { startPosition, currentPosition, startTime } = dragData;
      const duration = Date.now() - startTime;
      const deltaX = currentPosition.x - startPosition.x;
      const deltaY = currentPosition.y - startPosition.y;
      const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
      const velocity = {
        x: deltaX / duration,
        y: deltaY / duration,
      };

      // 判断方向
      let direction: 'horizontal' | 'vertical' | 'diagonal' = 'diagonal';
      const absX = Math.abs(deltaX);
      const absY = Math.abs(deltaY);

      if (absX > absY * 2) direction = 'horizontal';
      else if (absY > absX * 2) direction = 'vertical';

      // 判断手势类型
      const speed = Math.sqrt(
        velocity.x * velocity.x + velocity.y * velocity.y
      );
      const isFlick = speed > 0.5 && distance > 50;
      const isSlow = speed < 0.1 && duration > 500;

      return {
        velocity,
        direction,
        distance,
        duration,
        isFlick,
        isSlow,
      };
    },
    []
  );

  // 磁吸计算
  const calculateSnap = useCallback(
    (
      currentPos: { x: number; y: number },
      zones: SnapZone[]
    ): SnapZone | null => {
      if (!snapConfig.enabled) return null;

      let closestZone: SnapZone | null = null;
      let minDistance = snapConfig.threshold;

      for (const zone of zones) {
        const centerX = zone.x + zone.width / 2;
        const centerY = zone.y + zone.height / 2;
        const distance = Math.sqrt(
          Math.pow(currentPos.x - centerX, 2) +
            Math.pow(currentPos.y - centerY, 2)
        );

        if (distance < minDistance) {
          minDistance = distance;
          closestZone = zone;
        }
      }

      return closestZone;
    },
    [snapConfig]
  );

  // 拖拽目标验证
  const validateDrop = useCallback(
    (
      sourceRoom: Room,
      sourceDate: string,
      sourceStatus: RoomStatus,
      targetRoom: Room,
      targetDate: string
    ): {
      isValid: boolean;
      canDrop: boolean;
      reason?: string;
      confidence: number;
    } => {
      // 基础验证
      if (sourceRoom.id === targetRoom.id && sourceDate === targetDate) {
        return {
          isValid: false,
          canDrop: false,
          reason: '不能移动到相同位置',
          confidence: 0,
        };
      }

      // 状态验证
      if (!RoomStatusManager.canDrag(sourceStatus)) {
        return {
          isValid: false,
          canDrop: false,
          reason: '当前状态不允许拖拽',
          confidence: 0,
        };
      }

      // 目标房间状态验证
      const targetAvailability = availabilities.find(
        av => av.roomId === targetRoom.id && av.month === targetDate
      );
      const targetStatus = targetAvailability?.status;

      if (targetStatus && !RoomStatusManager.canDrop(targetStatus)) {
        return {
          isValid: false,
          canDrop: false,
          reason: `目标位置状态为${RoomStatusManager.getStatusConfig(targetStatus).label}，不允许放置`,
          confidence: 0,
        };
      }

      // 房间类型兼容性验证
      const confidence =
        sourceRoom.roomType === targetRoom.roomType ? 1.0 : 0.7;

      return {
        isValid: true,
        canDrop: true,
        confidence,
        reason: confidence < 1.0 ? '房间类型不同，但可以移动' : undefined,
      };
    },
    [availabilities]
  );

  // 开始拖拽
  const startDrag = useCallback(
    (
      event: React.MouseEvent | React.TouchEvent,
      room: Room,
      date: string,
      status: RoomStatus,
      cellBounds: { x: number; y: number; width: number; height: number }
    ) => {
      const clientX =
        'touches' in event ? event.touches[0].clientX : event.clientX;
      const clientY =
        'touches' in event ? event.touches[0].clientY : event.clientY;

      const startPosition = { x: clientX, y: clientY };
      const offset = {
        x: cellBounds.x - clientX,
        y: cellBounds.y - clientY,
      };

      // 初始化手势跟踪
      gestureRef.current = {
        startTime: Date.now(),
        positions: [{ x: clientX, y: clientY, time: Date.now() }],
      };

      const dragData: AdvancedDragData = {
        sourceRoom: room,
        sourceDate: date,
        sourceStatus: status,
        startPosition,
        currentPosition: startPosition,
        offset,
        cellBounds,
        startTime: Date.now(),
        gesture: {
          velocity: { x: 0, y: 0 },
          direction: 'diagonal',
          distance: 0,
          duration: 0,
          isFlick: false,
          isSlow: false,
        },
        trail: [],
      };

      setDragState(prev => ({
        ...prev,
        state: AdvancedDragState.PREPARING,
        dragData,
        isDragging: true,
        feedback: { ...prev.feedback, cursor: 'grabbing' },
      }));

      // 触觉反馈
      if (feedbackConfig.haptics && 'vibrate' in navigator) {
        navigator.vibrate(50);
      }

      // 延迟启动拖拽状态，允许准备动画
      setTimeout(() => {
        setDragState(prev => ({
          ...prev,
          state: AdvancedDragState.DRAGGING,
        }));
      }, 100);
    },
    [feedbackConfig.haptics]
  );

  // 更新拖拽
  const updateDrag = useCallback(
    (event: React.MouseEvent | React.TouchEvent) => {
      if (!dragState.isDragging || !dragState.dragData) return;

      const clientX =
        'touches' in event ? event.touches[0].clientX : event.clientX;
      const clientY =
        'touches' in event ? event.touches[0].clientY : event.clientY;

      const currentPosition = { x: clientX, y: clientY };

      // 更新手势数据
      gestureRef.current.positions.push({
        x: clientX,
        y: clientY,
        time: Date.now(),
      });

      // 保持最近20个位置点
      if (gestureRef.current.positions.length > 20) {
        gestureRef.current.positions = gestureRef.current.positions.slice(-20);
      }

      // 计算手势
      const gesture = enableGestures
        ? analyzeGesture({
            ...dragState.dragData,
            currentPosition,
          })
        : dragState.dragData.gesture;

      // 更新轨迹
      const trail = [
        ...dragState.dragData.trail,
        { x: clientX, y: clientY, timestamp: Date.now() },
      ];
      if (trail.length > 10) trail.shift(); // 保持轨迹长度

      // 计算磁吸
      const snapTarget = calculateSnap(currentPosition, snapZones);
      const isSnapping = !!snapTarget;

      // 应用磁吸
      let finalPosition = currentPosition;
      if (isSnapping && snapTarget) {
        const snapCenterX = snapTarget.x + snapTarget.width / 2;
        const snapCenterY = snapTarget.y + snapTarget.height / 2;

        finalPosition = {
          x:
            currentPosition.x +
            (snapCenterX - currentPosition.x) * snapConfig.strength,
          y:
            currentPosition.y +
            (snapCenterY - currentPosition.y) * snapConfig.strength,
        };
      }

      // 查找拖拽目标
      const roomIndex = Math.floor(
        (finalPosition.y + dragState.dragData.offset.y) / config.cellHeight
      );
      const dateIndex = Math.floor(
        (finalPosition.x +
          dragState.dragData.offset.x -
          config.roomTypeWidth -
          config.roomNumberWidth) /
          config.cellWidth
      );

      let dropTarget: AdvancedDropTarget | null = null;

      if (
        roomIndex >= 0 &&
        roomIndex < rooms.length &&
        dateIndex >= 0 &&
        dateIndex < dates.length
      ) {
        const targetRoom = rooms[roomIndex];
        const targetDate = dates[dateIndex];

        const validation = validateDrop(
          dragState.dragData.sourceRoom,
          dragState.dragData.sourceDate,
          dragState.dragData.sourceStatus,
          targetRoom,
          targetDate
        );

        dropTarget = {
          room: targetRoom,
          date: targetDate,
          position: finalPosition,
          isValid: validation.isValid,
          canDrop: validation.canDrop,
          reason: validation.reason,
          confidence: validation.confidence,
          snapDistance: snapTarget
            ? Math.sqrt(
                Math.pow(
                  finalPosition.x - (snapTarget.x + snapTarget.width / 2),
                  2
                ) +
                  Math.pow(
                    finalPosition.y - (snapTarget.y + snapTarget.height / 2),
                    2
                  )
              )
            : 0,
        };
      }

      setDragState(prev => ({
        ...prev,
        state: isSnapping
          ? AdvancedDragState.SNAPPING
          : AdvancedDragState.DRAGGING,
        dragData: prev.dragData
          ? {
              ...prev.dragData,
              currentPosition: finalPosition,
              gesture,
              trail,
            }
          : null,
        dropTarget,
        snapTarget,
        isSnapping,
        canDrop: dropTarget?.canDrop || false,
      }));

      // 性能监控
      if (performanceMode === 'high') {
        updatePerformance();
      }
    },
    [
      dragState.isDragging,
      dragState.dragData,
      enableGestures,
      calculateSnap,
      snapZones,
      snapConfig.strength,
      validateDrop,
      rooms,
      dates,
      config,
      performanceMode,
      updatePerformance,
    ]
  );

  // 结束拖拽
  const endDrag = useCallback(() => {
    if (!dragState.isDragging || !dragState.dragData || !dragState.dropTarget) {
      cancelDrag();
      return;
    }

    const { dragData, dropTarget } = dragState;

    if (dropTarget.canDrop) {
      setDragState(prev => ({
        ...prev,
        state: AdvancedDragState.COMPLETING,
      }));

      // 触觉反馈
      if (feedbackConfig.haptics && 'vibrate' in navigator) {
        navigator.vibrate([50, 50, 100]);
      }

      // 执行拖拽完成回调
      setTimeout(() => {
        onDragComplete(
          dragData.sourceRoom,
          dragData.sourceDate,
          dropTarget.room,
          dropTarget.date
        );

        // 重置状态
        setDragState({
          state: AdvancedDragState.IDLE,
          dragData: null,
          dropTarget: null,
          snapTarget: null,
          isDragging: false,
          canDrop: false,
          isSnapping: false,
          feedback: { ...feedbackConfig, cursor: 'grab' },
          performance: { frameRate: 60, renderTime: 0, memoryUsage: 0 },
        });
      }, 200);
    } else {
      cancelDrag();
    }
  }, [dragState, onDragComplete, feedbackConfig]);

  // 取消拖拽
  const cancelDrag = useCallback(() => {
    setDragState({
      state: AdvancedDragState.IDLE,
      dragData: null,
      dropTarget: null,
      snapTarget: null,
      isDragging: false,
      canDrop: false,
      isSnapping: false,
      feedback: { ...feedbackConfig, cursor: 'grab' },
      performance: { frameRate: 60, renderTime: 0, memoryUsage: 0 },
    });

    // 取消RAF
    if (rafRef.current) {
      cancelAnimationFrame(rafRef.current);
    }
  }, [feedbackConfig]);

  // 渲染拖拽预览
  const renderDragPreview = useCallback(
    (ctx: CanvasRenderingContext2D) => {
      if (!dragState.isDragging || !dragState.dragData) return;

      const { dragData, dropTarget, isSnapping } = dragState;
      const { currentPosition, offset, cellBounds } = dragData;

      // 绘制拖拽轨迹
      if (dragData.trail.length > 1) {
        ctx.save();
        ctx.globalAlpha = 0.3;
        ctx.strokeStyle = '#667eea';
        ctx.lineWidth = 2;
        ctx.lineCap = 'round';
        ctx.lineJoin = 'round';

        ctx.beginPath();
        dragData.trail.forEach((point, index) => {
          if (index === 0) {
            ctx.moveTo(point.x + offset.x, point.y + offset.y);
          } else {
            ctx.lineTo(point.x + offset.x, point.y + offset.y);
          }
        });
        ctx.stroke();
        ctx.restore();
      }

      // 绘制主拖拽元素
      const x = currentPosition.x + offset.x;
      const y = currentPosition.y + offset.y;

      ctx.save();

      // 阴影效果
      ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
      ctx.shadowBlur = 15;
      ctx.shadowOffsetX = 3;
      ctx.shadowOffsetY = 3;

      // 状态相关样式
      const statusConfig = RoomStatusManager.getStatusConfig(
        dragData.sourceStatus
      );

      if (dropTarget?.canDrop) {
        ctx.fillStyle = '#28a745';
        ctx.globalAlpha = 0.9;
      } else if (dropTarget && !dropTarget.canDrop) {
        ctx.fillStyle = '#dc3545';
        ctx.globalAlpha = 0.8;
      } else {
        ctx.fillStyle = statusConfig.backgroundColor;
        ctx.globalAlpha = 0.95;
      }

      // 绘制拖拽卡片
      ctx.fillRect(x, y, cellBounds.width, cellBounds.height);

      // 边框
      ctx.strokeStyle = dropTarget?.canDrop
        ? '#28a745'
        : dropTarget
          ? '#dc3545'
          : statusConfig.borderColor;
      ctx.lineWidth = isSnapping ? 3 : 2;
      ctx.strokeRect(x, y, cellBounds.width, cellBounds.height);

      ctx.restore();

      // 绘制磁吸指示器
      if (isSnapping && dragState.snapTarget) {
        const snapZone = dragState.snapTarget;
        ctx.save();
        ctx.strokeStyle = '#28a745';
        ctx.lineWidth = 2;
        ctx.setLineDash([5, 5]);
        ctx.strokeRect(snapZone.x, snapZone.y, snapZone.width, snapZone.height);
        ctx.restore();
      }
    },
    [dragState]
  );

  // 清理effect
  useEffect(() => {
    return () => {
      if (rafRef.current) {
        cancelAnimationFrame(rafRef.current);
      }
    };
  }, []);

  return {
    dragState,
    startDrag,
    updateDrag,
    endDrag,
    cancelDrag,
    renderDragPreview,
    setSnapZones,
  };
};

export default useAdvancedDragDrop;
